package com.jessechanrui.template.req18.pdf.itext.pdf;

import cn.com.agree.afa.svc.javaengine.context.JavaDict;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;

/**
 * @author lw
 */
public class CommonPdf extends PdfUtils{
	/** 字体文件路径*/
	private static final String FONT_PATH = "/export/app/afa/workspace/projects/IBS_JJP/apps/IBSJJPSERVE/conf/font/";
	/** 签章文件路径*/
	private static final String SIGN_IMAGE_PATH = "/export/app/afa/workspace/projects/IBS_JJP/apps/IBSJJPSERVE/conf/image/";

	
	/** 生成PDF-工人工资专项代发结果*/
	public String creatPdf1(JavaDict req, ArrayList<JavaDict> formList,String filePath,String fileName) throws Exception {
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
		String filePathName = filePath+fileName;
		
		//生成JSON-工人工资专项代发结果
		CommonJson.packJsonFile1(req, formList, filePath, fileName);
		//将JSON转为PDF
		return jsonToPdf(filePathName);
	}
	
	/** 生成PDF-工人工资专项代发结果详情*/
	public String creatPdf2(JavaDict req, ArrayList<JavaDict> formList,String filePath,String fileName) throws Exception {
		File file = new File(filePath);
		if (!file.exists()) {
			file.mkdirs();
		}
		String filePathName = filePath+fileName;
		
		//生成JSON-工人工资专项代发结果详情
		CommonJson.packJsonFile2(req, formList, filePath, fileName);
		//将JSON转为PDF
		return jsonToPdf(filePathName);
	}

	/**
	 * JSON转为PDF
	 * @throws Exception  
	 */
	public String jsonToPdf(String filePathName) throws Exception {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePathName), Charset.forName("UTF-8")));
		String jsonLine = "";
		String line;
		while ((line = br.readLine()) != null) {
			jsonLine += line;
		}
		//创建文本对象
		Document document = new Document(PageSize.A4);

		String outputFileName = filePathName.replace(".json", ".pdf");
		//初始化pdf输出对象
		PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(outputFileName));
		
		JSONArray lineList = JSON.parseArray(jsonLine);
		for (int num = 0; num < lineList.size(); num++) {
			this.render(num, document, pdfWriter, lineList.get(num));
		}

		document.close();
		br.close();
		return outputFileName;
	}
	
	/**
	 * 处理json节点
	 */
	public void render(int index, Document document, PdfWriter pdfWriter, Object object) throws Exception {
		JSONObject jsonObj = (JSONObject) JSON.parse(object.toString());
		String dataType = (String) jsonObj.get("type");

		if (PAGE.equals(dataType)) {
			//页面节点
			if (index == 0) {
				this.renderPage(document, object);
				document.open();
				
			} else {
				this.renderPage(document, object);
				document.newPage();
			}
		} else if (PARAGRAPH.equals(dataType)) {
			//段落节点
			this.renderParagraph(document, object);
		} else if (TABLE.equals(dataType)) {
			//表格节点
			this.renderTable(document, object);
		} else if (PAGENUMBER.equals(dataType)) {
			//页码
			this.renderPageNumber(document, pdfWriter, object);
		} else if (SIGNATURE.equals(dataType)) {
			//签章
			this.renderSignature(document, pdfWriter, object);
		}

	}


	/**
	 * 创建页面
	 */
	public void renderPage(Document document, Object object) throws Exception {
		JSONObject pageObj = JSON.parseObject(object.toString());
		float left = (Float) pageObj.getFloatValue("left");
		float right = (Float) pageObj.getFloatValue("right");
		float up = (Float) pageObj.getFloatValue("up");
		float down = (Float) pageObj.getFloatValue("down");

		document.setMargins(mm2pt(left), mm2pt(right), mm2pt(up), mm2pt(down));
	}
	
	/**
	 * 渲染段落对象
	 */
	public Paragraph renderParagraph(Document document, Object object) throws Exception {
		JSONObject jsonObj = (JSONObject) JSON.parse(object.toString());

		JSONObject paraObj;
		Paragraph para;

		Object jsonObjValue = jsonObj.get("value");
		if (jsonObjValue instanceof String || jsonObjValue instanceof JSONObject || jsonObjValue == null) {
			// 如果是对象，则就一个chunk
			paraObj = (JSONObject) jsonObj;
			para = new Paragraph(this.renderChunk(paraObj));
		} else {
			// 如果是列表对象，也就是一个段落存在多个 chunk
			para = new Paragraph();
			JSONArray paraObjList = (JSONArray) jsonObjValue;
			for (int num = 0; num < paraObjList.size(); num++) {
				JSONObject chunkObj = (JSONObject) paraObjList.get(num);
				para.add(this.renderChunk(chunkObj));
			}
			paraObj = jsonObj;
		}

		int alignMent = (Integer) paraObj.getOrDefault("alignMent", 0);
		float firstlineIndent = objectToFloat(paraObj, "firstlineIndent", 0f);
		float indentationLeft = objectToFloat(paraObj, "indentationLeft", 0f);
		float indentationRight = objectToFloat(paraObj, "indentationRight", 0f);
		float spacingBefore = objectToFloat(paraObj, "spacingBefore", 0f);
		float spacingAfter = objectToFloat(paraObj, "spacingAfter", 0f);
		float leading = objectToFloat(paraObj, "leading", 10f);

		para.setAlignment(alignMent);
		para.setFirstLineIndent(firstlineIndent);
		para.setIndentationLeft(indentationLeft);
		para.setIndentationRight(indentationRight);
		para.setSpacingBefore(spacingBefore);
		para.setSpacingAfter(spacingAfter);
		if (leading > 0) {
			para.setLeading(leading);
		}
		if (document != null) {
			document.add(para);
		}
		
		return para;
	}

	/**
	 * 渲染文本块对象
	 * 
	 * @param object
	 * @return
	 * @throws DocumentException
	 * @throws IOException
	 */
	public Chunk renderChunk(Object object) throws Exception {
		JSONObject chunkObj = JSON.parseObject(object.toString());

		String value = (String) chunkObj.getOrDefault("value", "");
		Boolean isUnderLine = (Boolean) chunkObj.getOrDefault("isUnderLine", false);

		Chunk chunk = new Chunk(value);
		chunk.setFont(this.renderFont(object));
		
		if (isUnderLine) {
			float thickness = objectToFloat(chunkObj, "thickness", 1.0f);
			float yPosition = objectToFloat(chunkObj, "underLineYPosition", -2f);
			chunk.setUnderline(thickness, yPosition);
		}
		
		return chunk;
	}
	
	/**
	 * 渲染字体
	 */
	public Font renderFont(Object object) throws Exception {
		JSONObject fontObj = JSON.parseObject(object.toString());
		String fontFamily = (String) fontObj.getOrDefault("fontFamily", "STSong-Light");
		float fontSize = objectToFloat(fontObj, "fontSize", 12.0f);
		int fontStyle = (Integer) fontObj.getOrDefault("fontStyle", Font.NORMAL);
		String fontColor = (String) fontObj.getOrDefault("fontColor", "0, 0, 0");
		
		BaseFont stFont;
		if (STSONGLIGHT.equals(fontFamily)) {
			stFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
		} else {
			stFont = BaseFont.createFont(FONT_PATH + fontFamily + ".ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
		}
		Font font = new Font(stFont, fontSize, fontStyle, str2color(fontColor));
		
		return font;
	}
	

	/**
	 * 渲染表格对象
	 */
	public PdfPTable renderTable(Document document, Object object) throws Exception {
		JSONObject tableObj = JSON.parseObject(object.toString());

		int columnNum = (Integer) tableObj.getOrDefault("columnNum", 1);
		String widths = (String) tableObj.getOrDefault("widths", "1");
		String[] widthsStr = widths.split(", ");
		float[] widthsFloat = new float[widthsStr.length];
		for (int i = 0; i < widthsStr.length; i++) {
			widthsFloat[i] = Float.parseFloat(widthsStr[i]);
		}
		//边框
		int border = (Integer) tableObj.getOrDefault("border", 15);
		Object borderWidth = tableObj.get("borderWidth");
		Object borderColor = tableObj.get("borderColor");
		//空白
		float spacingBefore = objectToFloat(tableObj, "spacingBefore", 0f);
		float spacingAfter = objectToFloat(tableObj, "spacingAfter", 0f);
		//高度
		float minimunHeight = objectToFloat(tableObj, "minimunHeight", 14f);
		//单元格边距
		float padding = objectToFloat(tableObj, "padding", 0f);
			
		PdfPTable table = new PdfPTable(columnNum);
		if(document != null) {			
			Rectangle pageSize = document.getPageSize();
			table.setTotalWidth(pageSize.getWidth() - document.leftMargin() - document.rightMargin());
			table.setLockedWidth(true);
		}else {
			table.setWidthPercentage(100);
			table.setLockedWidth(false);
		}
		table.setWidths(widthsFloat);
		table.setSpacingBefore(spacingBefore);
		table.setSpacingAfter(spacingAfter);
		
		Object value = tableObj.get("value");
		JSONArray tableList = JSON.parseArray(value.toString());
		//循环行
		for (int num = 0; num < tableList.size(); num++) {
			JSONArray colList = tableList.getJSONArray(num);
			//循环列
			for (int subNum = 0; subNum < colList.size(); subNum++) {
				JSONObject colObject = (JSONObject) colList.get(subNum);

				PdfPCell cell = new PdfPCell();
				
				String dataType = (String) colObject.get("type");

				if (TABLE.equals(dataType)) {
					//嵌套表格
					PdfPTable pdfTable = renderTable(null, colObject);
					cell = new PdfPCell(pdfTable);
				}else {
					//段落					
					Paragraph para = this.renderParagraph(null, colObject.toString());
					borderWidth =  colObject.get("borderWidth")==null?borderWidth:colObject.get("borderWidth");
					borderColor =  colObject.get("borderColor")==null?borderColor:colObject.get("borderColor");
					
					cell.addElement(para);
				}
				if (num == 0) {
					int headVa = (Integer) tableObj.getOrDefault("headVA", 0);
					int headHa = (Integer) tableObj.getOrDefault("headHA", 0);
					String color = (String) tableObj.getOrDefault("headBgColor", "255, 255, 255");
					
					cell.setVerticalAlignment(headVa);
					cell.setHorizontalAlignment(headHa);
					cell.setBackgroundColor(str2color(color));
				}else if(num > 0){
					int bodyVa = (Integer) tableObj.getOrDefault("bodyVA", 0);
					int bodyHa = (Integer) tableObj.getOrDefault("bodyHA", 0);
					String color = (String) tableObj.getOrDefault("bodyBgColor", "255, 255, 255");
					
					cell.setVerticalAlignment(bodyVa);
					cell.setHorizontalAlignment(bodyHa);
					cell.setBackgroundColor(str2color(color));
				}
				cell.setBorder(border);
				if(border!=0) {					
					if(borderWidth!=null) {					
						cell.setBorderWidth(((BigDecimal)borderWidth).floatValue());
					}
					if(borderColor!=null) {
						cell.setBorderColor(str2color((String)borderColor));
					}
				}
				cell.setMinimumHeight(minimunHeight);
				cell.setPadding(padding);
				
				table.addCell(cell);
			}
		}
		if (document != null) {
			document.add(table);
		}
		return table;
	}
	
	/**
	 * 添加页码
	 */
	public void renderPageNumber(Document document, PdfWriter pdfWriter, Object object) throws Exception {
		//页码对象
		Rectangle pageSize = document.getPageSize();
		//获取当前页内容
		PdfContentByte pcb = pdfWriter.getDirectContent();
		pcb.beginText();
		//模版
		PdfTemplate template = pcb.createTemplate(pageSize.getWidth(), pageSize.getHeight());
		template.beginText();
		template.setFontAndSize(BaseFont.createFont(), 10);
		Paragraph p = this.renderParagraph(null, object);
		//写入模版
		JSONObject pageNumObj = JSON.parseObject(object.toString());
		String absolutePosition = (String) pageNumObj.getOrDefault("absolutePosition", "260, 30");
		String[] absolutePositionArr = absolutePosition.split(", ");
		ColumnText.showTextAligned(template, Element.ALIGN_LEFT, new Phrase(p), Float.parseFloat(absolutePositionArr[0]), Float.parseFloat(absolutePositionArr[1]), 0);
		template.endText();
		pcb.addTemplate(template, 0, 0);
		pcb.endText();
		pcb.stroke();
	}
	

	/**
	 * 添加签章
	 */
	private void renderSignature(Document document, PdfWriter pdfWriter, Object object) throws Exception {
		JSONObject imageObj = JSON.parseObject(object.toString());
		String scaleToFit = (String) imageObj.getOrDefault("scaleToFit", "40, 40");
		String absolutePosition = (String) imageObj.getOrDefault("absolutePosition", "0, 0");
		String[] scaleToFitArr = scaleToFit.split(", ");
		String[] absolutePositionArr = absolutePosition.split(", ");
		//获取当前页内容
		PdfContentByte pcb = pdfWriter.getDirectContent();
		pcb.beginText();
		//图片
		Image image = Image.getInstance(CommonPdf.SIGN_IMAGE_PATH + "baidi.png");
		image.scaleToFit(mm2pt(Float.parseFloat(scaleToFitArr[0])), mm2pt(Float.parseFloat(scaleToFitArr[1])));
		image.setAbsolutePosition(Float.parseFloat(absolutePositionArr[0]), Float.parseFloat(absolutePositionArr[1]));
		pcb.addImage(image);
		pcb.endText();
		pcb.stroke();
	}
	

}
